package wc;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class Count {
	ArrayList<String> line=new ArrayList<>();
	Map<String,Integer> map=new HashMap<String,Integer>();
	Map<String,Integer> map2=new HashMap<String,Integer>();
	public Count(ArrayList<String> line){
		this.line=line;
	}
	
	public int CountChars(){
		int count=0;
		for(int i=0;i<line.size();i++){
			String str=line.get(i);
			for(int j=0;j<str.length();j++){
				char c=str.charAt(j);
				if(('A'<=c&&c<='Z')||('a'<=c&&c<='z')||c=='\n'||c=='\r'||c=='\t'){
					count++;
				}
			}	
		}
		return count;
	}
	
	public int CountWords(){
		int count=0;		
		for(int i=0;i<line.size();i++){
			String str=line.get(i);
			if(str.length()>=4){
				String[] words=str.split("[^a-zA-Z0-9]+");
				for (String word:words){
					int flag=0;
					char[] w=word.toCharArray();
					if(w.length>=4){
						for(int j=0;j<4;j++){
							if(!(('A'<=w[j]&&w[j]<='Z')||('a'<=w[j]&&w[j]<='z'))){
								flag=1;
								break;
							}
						}
					}
					else{
						flag=1;
					}
					
					if(flag==0){
						String s=word.toLowerCase();
						if(!map.containsKey(s)){
							count++;
							map.put(s, 1);
						}
						else{
							int num=map.get(s);
							map.put(s, ++num);
						}
					}
				}
			}
		}
		return count;
	}
	
	
	public int CountLine(){
		int count=0;
		for(int i=0;i<line.size();i++){
			String str=line.get(i);
			if(str.length()>0){
				count++;
			}
		}
		return count;
	}
	
	public ArrayList WordTop(int n,int count){
		ArrayList<Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
		Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {

            @Override
            public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
                if (o1.getValue() == o2.getValue()) {
                    return o1.getKey().compareTo(o2.getKey());
                }
                return o2.getValue() - o1.getValue();
            }

        });
		if(count<=n){
			return list;
		}
		else{
			for(int i=list.size()-1;i>=n;i--){
				list.remove(i);
			}
			return list;
		}
	}
	
	public Map CountPhrase(int m){
		String str=null;
		for(int i=0;i<line.size();i++){
			String s=line.get(i);
			if(i==0){
				str=s;
			}
			else{
				str=str+" "+s;
			}
		}
		//System.out.println(str);
		String[] words=str.split("[^a-zA-Z0-9]+");
		for (int i=0;i<words.length;i++){
			int flag=0;
			int p=i;
			String s=words[p].toLowerCase();
			if(map.containsKey(s)){
				String phrase=s;
				for(int j=1;j<m;j++){
					p++;
					if(((p)<words.length)&&(map.containsKey(words[p]))){
						phrase=phrase+" "+words[p];
						//System.out.println(p);
					}
					else{
						flag=1;
						break;
					}
				}
				if(flag==0){
					if(!map2.containsKey(phrase)){
						map2.put(phrase, 1);
					}
					else{
						int num=map2.get(phrase);
						map2.put(phrase, ++num);
					}
				}
			}
			
		}
		return map2;
	}

}
